#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>

#define CAN_INTERFACE "can0"

void setup_can_interface(int s) {
    struct ifreq ifr;
    struct sockaddr_can addr;

    strcpy(ifr.ifr_name, CAN_INTERFACE);
    ioctl(s, SIOCGIFINDEX, &ifr);

    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    bind(s, (struct sockaddr *)&addr, sizeof(addr));
}

void send_canfd_message(int s) {
    struct canfd_frame frame;

    frame.can_id = 0x123;
    frame.len = 16; // 发送16个字节的数据
    for (int i = 0; i < 16; i++) {
        frame.data[i] = i;
    }

    if (write(s, &frame, sizeof(struct canfd_frame)) != sizeof(struct canfd_frame)) {
        perror("Write");
        exit(EXIT_FAILURE);
    }

    printf("Sent CAN FD message\n");
  
}

void receive_canfd_message(int s) {
    struct canfd_frame frame;
    int nbytes = read(s, &frame, sizeof(struct canfd_frame));
    if (nbytes < 0) {
        perror("Read");
        exit(EXIT_FAILURE);
    }

    printf("Received CAN FD message with ID: 0x%X\n", frame.can_id);
    printf("Data: ");
    for (int i = 0; i < frame.len; i++) {
        printf("%02X ", frame.data[i]);
    }
    printf("\n");
}

int main() {
    int s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (s < 0) {
        perror("Socket");
        return 1;
    }

    int enable_canfd = 1;
    if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &enable_canfd, sizeof(enable_canfd))) {
        perror("setsockopt CAN_RAW_FD_FRAMES");
        return 1;
    }

    setup_can_interface(s);

    send_canfd_message(s);
    
    receive_canfd_message(s);

    close(s);
    return 0;
}

